package com.todo.strategy.online.application.frontend.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.todo.common.common.entity.response.BizPageResponse;
import com.todo.common.common.entity.response.BizResponse;
import com.todo.common.common.entity.response.page.PageResult;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.strategy.online.application.convert.StrategyConvert;
import com.todo.strategy.online.application.entity.bo.PlanContentBO;
import com.todo.strategy.online.application.entity.bo.PlanSetBO;
import com.todo.strategy.online.application.entity.bo.StrategyDetailBO;
import com.todo.strategy.online.application.entity.bo.StrategyInfoBO;
import com.todo.strategy.online.application.entity.condition.StrategyInfoConditionBO;
import com.todo.strategy.online.application.service.StrategyInfoService;
import com.todo.strategy.online.application.frontend.service.UserStrategyAggService;
import com.todo.strategy.online.application.remote.UserInfoRemoteService;
import com.todo.strategy.online.application.service.PlanContentService;
import com.todo.strategy.online.application.service.PlanSetService;
import com.todo.strategy.online.iface.request.*;
import com.todo.strategy.online.iface.response.StrategyBaseVO;
import com.todo.strategy.online.iface.response.UserStrategyDetailVO;
import com.todo.user.api.response.BaseUserInfoResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * (StrategyInfo)表服务实现类
 *
 * @author zhangwenxiang
 * @since 2024-03-04 00:19:49
 */
@Slf4j
@Service("userStrategyAggService")
public class UserStrategyAggServiceImpl implements UserStrategyAggService {

    @Resource
    private StrategyInfoService userStrategyService;
    @Resource
    private UserInfoRemoteService userInfoRemoteService;
    @Resource
    private PlanSetService planSetService;
    @Resource
    private PlanContentService planContentService;

    @Override
    public BizResponse<Boolean> insertUserStrategy(InsertUserStrategyParam param) {
        if (param == null || !param.baseCheck()) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        PlanSetBO planSetBO = planSetService.queryPlanSetById(param.getPlanId());
        if (planSetBO == null) {
            log.error("UserStrategyAggService#insertUserStrategy 新增用户攻略失败，计划不存在 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.paramError("计划不存在，请刷新后重试");
        }
        if (!planSetBO.getUserId().equals(param.get_user().getUserId())) {
            log.error("UserStrategyAggService#insertUserStrategy 新增用户攻略失败，用户id不匹配 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.paramError("非创建用户无法操作");
        }
        StrategyInfoBO strategyInfoBO = userStrategyService.queryStrategyInfoPOByPlanId(param.get_user().getUserId(), param.getPlanId());
        if (strategyInfoBO != null) {
            log.error("UserStrategyAggService#insertUserStrategy 新增用户攻略失败，用户攻略已存在 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.paramError("用户攻略已存在，刷新后即可浏览");
        }
        StrategyInfoBO insertStrategy = StrategyConvert.convertToStrategyInfoBO(param);
        Boolean insertResult = userStrategyService.insertStrategyInfo(insertStrategy);
        return BizResponse.success(insertResult);
    }

    @Override
    public BizResponse<Boolean> updateUserStrategy(UpdateUserStrategyParam param) {
        if (param == null || !param.baseCheck()) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        StrategyInfoBO strategyInfoBO = userStrategyService .queryStrategyInfoById(param.getStrategyId());
        if (strategyInfoBO == null) {
            log.error("UserStrategyAggService#updateUserStrategy 更新用户攻略失败，用户攻略不存在 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.paramError("用户攻略不存在，请刷新后重试");
        }
        if (!strategyInfoBO.getUserId().equals(param.get_user().getUserId())) {
            log.error("UserStrategyAggService#updateUserStrategy 更新用户攻略失败，用户id不匹配 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.paramError("非创建用户无法操作");
        }
        if (!strategyInfoBO.getPlanId().equals(param.getPlanId())) {
            log.error("UserStrategyAggService#updateUserStrategy 更新用户攻略失败，计划id不匹配 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.paramError("计划清单不匹配，请刷新后重试");
        }
        StrategyInfoBO updateStrategy = StrategyConvert.convertToStrategyInfoBO(param);
        Boolean updateResult = userStrategyService.updateStrategyInfo(updateStrategy);
        return BizResponse.success(updateResult);
    }

    @Override
    public BizResponse<Boolean> removeUserStrategy(RemoveUserStrategyParam param) {
        if (param == null || !param.baseCheck()) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        StrategyInfoBO strategyInfoBO = userStrategyService.queryStrategyInfoById(param.getStrategyId());
        if (strategyInfoBO == null) {
            log.info("UserStrategyAggService#removeUserStrategy 删除用户攻略完成，用户攻略不存在，默认成功 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.success(true);
        }
        if (!strategyInfoBO.getUserId().equals(param.get_user().getUserId())) {
            log.error("UserStrategyAggService#removeUserStrategy 删除用户攻略失败，用户id不匹配 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.paramError("非创建用户无法操作");
        }
        Boolean removeResult = userStrategyService.removeStrategyInfoById(param.getStrategyId());
        return BizResponse.success(removeResult);
    }

    @Override
    public BizPageResponse<StrategyBaseVO> queryUserStrategyListByUserId(QueryUserStrategyByUserIdParam param) {
        if (param == null || !param.baseCheck()) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        BizResponse<BaseUserInfoResponse> userinfoResponse = userInfoRemoteService.queryBaseUserAccountInfoByUserId(param.get_user().getUserId());
        if (userinfoResponse == null || !userinfoResponse.isSuccess() || userinfoResponse.getData() == null) {
            log.error("UserStrategyAggService#queryUserStrategyListByUserId 查询用户攻略列表完成，用户不存在 入参：【{}】", JSONObject.toJSONString(param));
            return BizPageResponse.success();
        }

        StrategyInfoConditionBO queryCondition = StrategyConvert.convertToStrategyInfoConditionBO(param);
        PageResult<StrategyInfoBO> pageResult = userStrategyService.queryStrategyInfoByCondition(queryCondition);
        if (pageResult == null) {
            log.info("UserStrategyAggService#queryUserStrategyListByUserId 查询用户攻略列表失败，用户攻略不存在 入参：【{}】", JSONObject.toJSONString(param));
            return BizPageResponse.success();
        }
        if (CollectionUtils.isEmpty(pageResult.getResults())) {
            return BizPageResponse.success(new PageResult<>(null, pageResult.getPageNum(), pageResult.getPageSize(), pageResult.getTotal()));
        }

        List<StrategyBaseVO> strategyBaseVOList = new ArrayList<>();
        for (StrategyInfoBO strategyInfoBO : pageResult.getResults()) {
            PlanSetBO planSetBO = planSetService.queryPlanSetById(strategyInfoBO.getPlanId());
            if (planSetBO == null) {
                continue;
            }
            StrategyBaseVO strategyBaseVO = StrategyConvert.buildStrategyBaseVO(strategyInfoBO, planSetBO, userinfoResponse.getData());
            strategyBaseVOList.add(strategyBaseVO);
        }

        return BizPageResponse.success(new PageResult<>(strategyBaseVOList, pageResult.getPageNum(), pageResult.getPageSize(), pageResult.getTotal()));
    }

    @Override
    public BizResponse<UserStrategyDetailVO> queryUserStrategyById(QueryUserStrategyByIdParam param) {
        if (param == null || !param.baseCheck()) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        StrategyDetailBO strategyDetailBO = userStrategyService.queryStrategyDetailById(param.getStrategyId());
        if (strategyDetailBO == null || strategyDetailBO.getStrategyInfoBO() == null) {
            log.error("UserStrategyAggService#queryUserStrategyById 查询用户攻略详情失败，用户攻略不存在 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.success();
        }
        StrategyInfoBO strategyInfoBO = strategyDetailBO.getStrategyInfoBO();
        BizResponse<BaseUserInfoResponse> userAccountResponse = userInfoRemoteService.queryBaseUserAccountInfoByUserId(strategyInfoBO.getUserId());
        if (userAccountResponse == null || !userAccountResponse.isSuccess() || userAccountResponse.getData() == null) {
            log.error("UserStrategyAggService#queryUserStrategyById 查询用户攻略列表完成，用户不存在 入参：【{}】", JSONObject.toJSONString(param));
            return BizResponse.success();
        }

        List<PlanContentBO> planContentResponses = planContentService.queryPlanContentByPlanId(param.get_user().getUserId(), strategyInfoBO.getPlanId());
        Map<Long/*planRelationId*/, PlanContentBO> relationIdMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(planContentResponses)) {
            relationIdMap = planContentResponses
                    .stream()
                    .collect(Collectors.toMap(PlanContentBO::getPlanRelationId, item -> item, (k1, k2) -> k1));
        }
        UserStrategyDetailVO userStrategyDetailVO = StrategyConvert.buildUserStrategyDetailVO(strategyDetailBO, relationIdMap, userAccountResponse.getData());

        return BizResponse.success(userStrategyDetailVO);
    }
}
